/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package assignment_cp3120.registeruser;

import assignment_cp3120.startup.StartupView;
import assignment_cp3120.view.MainFrame;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.text.ParseException;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.text.MaskFormatter;
import javax.swing.JOptionPane;

/**
 * View for the register user usecase
 * @author Administrator
 */
public class RegisterUserView {
    private JLabel nameLabel;
    
    private JTextField firstNameField;
    private JTextField lastNameField;
    
    private JLabel dobLabel;
    
    private JFormattedTextField dayField;
    private JFormattedTextField monthField;
    private JFormattedTextField yearField;
    
    private JLabel addressAddLabel;
    private JLabel addressSuburbLabel;
    private JLabel addressStateLabel;
    private JLabel addressPostLabel;
    
    private JTextField addressAddField;
    private JTextField addressSuburbField ;
    private JTextField addressStateField;
    private JTextField addressPostField;    
    
    private JLabel instructionsLabel;
    private JLabel usernameLabel;
    private JLabel passwordLabel;
    private JLabel confirmPasswordLabel;
    
    private JTextField usernameField;
    private JPasswordField passwordField;
    private JPasswordField confirmPasswordField;
    
    private GroupLayout layout;
    private JPanel centerPanel;
    
    private JButton submitButton;
    private JButton cancelButton;
    
    private Dimension seperatorSize;
    
    private RegisterUserModel model;
    
    private MainFrame frame;
    private JPanel previousContents;

    /* author Tristan
     * Field constraint variables
     * All the error checking variable the for input fields
     */
    private final String TITLE_ERROR = "Invalid Input!";
    private final int NAME_LENGTH = 26;
    private final int ADDRESS_LENGTH = 50;
    private final int SUBURB_LENGTH = 26;
    private final int STATE_LENGTH = 6;
    private final int PASSWORD_LENGTH = 14;
    /**
     * Default constructor calls Constructor(model, frame) with new values
     */
    public RegisterUserView() {
        this(new RegisterUserModel(), new StartupView());        
    }
    /**
     * Constructor calls Constructor(model, frame) with new model and the frame passed to the constructor
     */
    public RegisterUserView(StartupView mainFrame){
        this(new RegisterUserModel(), mainFrame);
    }
    /**
     * Constructor sets the model and frame to the inputs and calls createPanel()
     */
    public RegisterUserView(RegisterUserModel model, StartupView mainFrame) {
        this.model = model;
        createPanel();
        frame = mainFrame;
    }
    /**
     * Creates the contents panel with a group layout
     */
    private void createPanel(){
        initName();
        initDOB();
        initAdrress();
        initUserPass();
        initButtons();
                
        JPanel seperator = new JPanel();
        seperatorSize = new Dimension(0, 20);
        seperator.setMaximumSize(seperatorSize);
        
        centerPanel = new JPanel();
        layout = new GroupLayout(centerPanel);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        
        centerPanel.setLayout(layout);
        
        //horizontal group
        layout.setHorizontalGroup(layout.createSequentialGroup()
            //first column
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                //2 name fields, first and last name
                .addGroup(layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(nameLabel) 
                        .addComponent(firstNameField))
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(lastNameField))
                )
                
                .addComponent(dobLabel)
                //3 date of bith fields in a group inside the main group.
                .addGroup(layout.createSequentialGroup()                    
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(dayField))
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(monthField))
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)     
                        .addComponent(yearField))
                )
                
                .addGroup(layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(addressAddLabel)                
                        .addComponent(addressStateLabel)
                        .addComponent(addressAddField)                
                        .addComponent(addressStateField))
                 
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(addressSuburbLabel)
                        .addComponent(addressPostLabel)
                        .addComponent(addressSuburbField)
                        .addComponent(addressPostField))
                 )             
                .addComponent(usernameLabel)
                .addComponent(usernameField)
                
                //pasword and comfirm
                .addGroup(layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(passwordLabel)
                        .addComponent(passwordField))
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(confirmPasswordLabel)
                        .addComponent(confirmPasswordField))
                )
                .addGroup(layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(submitButton))
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(cancelButton))
                )
        ));
        
        layout.linkSize(SwingConstants.HORIZONTAL, submitButton, cancelButton);
        
        //vertical group
        layout.setVerticalGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(nameLabel))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(firstNameField)
                .addComponent(lastNameField))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(dobLabel))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)    
                    .addComponent(dayField)
                    .addComponent(monthField)
                    .addComponent(yearField))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)                        
                .addComponent(addressAddLabel)
                .addComponent(addressSuburbLabel))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(addressAddField)
                .addComponent(addressSuburbField))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(addressStateLabel)
                .addComponent(addressPostLabel))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(addressStateField)
                .addComponent(addressPostField))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(usernameLabel))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(usernameField))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(passwordLabel)
                .addComponent(confirmPasswordLabel))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(passwordField)
                .addComponent(confirmPasswordField))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(submitButton)
                .addComponent(cancelButton))
        );
    }
    /**
     * Initialize the name section of the form
     */
    public void initName(){
        nameLabel = new JLabel("Name:");
        nameLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        
        firstNameField = new JTextField();
        lastNameField = new JTextField();
    }
    /**
     * Initialize the DOB setion of the form
     */
    public void initDOB(){
        dobLabel = new JLabel("DOB: dd/mm/yyyy");
        dobLabel.setHorizontalAlignment(SwingConstants.RIGHT);

        try {
            MaskFormatter format = new MaskFormatter("##");
            dayField = new JFormattedTextField(format);
            monthField = new JFormattedTextField(format);
            format = new MaskFormatter("####");
            yearField = new JFormattedTextField(format);
        }
        catch(ParseException e){System.out.println(e);}
    }
    /**
     * Initialize the address part of the form
     */
    public void initAdrress(){
        addressAddLabel = new JLabel("Address:");
        addressSuburbLabel = new JLabel("Suburb:");
        addressStateLabel = new JLabel("State:");
        addressPostLabel = new JLabel("Post Code:");
        
        addressAddLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        addressSuburbLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        addressStateLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        addressPostLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        
        addressAddField = new JTextField();
        addressSuburbField = new JTextField();
        addressStateField = new JTextField();
        addressPostField = new JTextField();
    }
    /**
     * Initialize username and password section
     */
    public void initUserPass(){
        instructionsLabel = new JLabel("Enter preffered username and password.");
        instructionsLabel.setHorizontalAlignment(SwingConstants.RIGHT);
        
        usernameLabel = new JLabel("Username:");
        usernameLabel.setHorizontalAlignment(SwingConstants.RIGHT);
    
        passwordLabel = new JLabel("Password:");
        passwordLabel.setHorizontalAlignment(SwingConstants.RIGHT);
      
        confirmPasswordLabel = new JLabel("Confirm Password:");
        confirmPasswordLabel.setHorizontalAlignment(SwingConstants.RIGHT);
      
        usernameField = new JTextField();
        passwordField = new JPasswordField();    
        confirmPasswordField = new JPasswordField();   
    }
    /**
     * Initialize the buttons
     */
    public void initButtons(){
        submitButton = new JButton("Submit");
        cancelButton = new JButton("Cancel");        
    }
    /**
     * Add listener to the buttons and set action commands
     * @param a
     * Action listener to add to the button
     */
    public void buttonListener(ActionListener a) {
        submitButton.setActionCommand(model.SUBMIT);
        submitButton.addActionListener(a);
        
        cancelButton.setActionCommand(model.CANCEL);
        cancelButton.addActionListener(a);
    }
    /**
     * Set the center contents of the frame to centerpanel and store the previous contents
     */
    public void showGUI(){
        previousContents = frame.getContents();
        frame.setContents(centerPanel);
        frame.setVisible(true);
    }
    /**
     * Restore the previos contents
     */
    public void hideGUI(){
        frame.setContents(previousContents);
    }
    /*This function checks that all the input fields are correct and using proper formating
     * If they are not, an error message is printed and the isValid variable is made false
     */
    public boolean validateForm(){
        boolean isValid = true;
       
        if(firstNameField.getText().isEmpty()){
            isValid = false;
            errorMessageBox("First name field is empty", TITLE_ERROR);
        }
        else if(firstNameField.getText().length() >= NAME_LENGTH) {
            isValid = false;
            errorMessageBox("First name is too long", TITLE_ERROR);
        }
        else if(lastNameField.getText().isEmpty()){
            isValid = false;
            errorMessageBox("Last name field is empty", TITLE_ERROR);
        }
        else if(lastNameField.getText().length() >= NAME_LENGTH){
            isValid = false;
            errorMessageBox("Last name is to long", TITLE_ERROR);
        }
        else if(Character.isDigit(dayField.getText().charAt(0)) != true){isValid = false;}
        else if(Character.isDigit(monthField.getText().charAt(0)) != true){isValid = false;}
        else if(Character.isDigit(yearField.getText().charAt(0)) != true){isValid = false;}
        
        else if(addressAddField.getText().isEmpty()){
            isValid = false;
            errorMessageBox("Address field is empty", TITLE_ERROR);
        }
        else if(addressAddField.getText().length() >= ADDRESS_LENGTH) {
            isValid = false;
            errorMessageBox("Address is to long", TITLE_ERROR);
        }
        else if(addressSuburbField.getText().isEmpty()){
            isValid = false;
            errorMessageBox("Suburb field is empty", TITLE_ERROR);
        }
        else if(addressSuburbField.getText().length() >= SUBURB_LENGTH){
            isValid = false;
            errorMessageBox("Suburb name is to long", TITLE_ERROR);
        }
        else if(addressStateField.getText().isEmpty()){
            isValid = false;
            errorMessageBox("State field is empty", TITLE_ERROR);
        }
        else if(addressStateField.getText().length() >= STATE_LENGTH){
            isValid = false;
            errorMessageBox("State name is to long", TITLE_ERROR);
        }
        else if(addressPostField.getText().isEmpty()){
            isValid = false;
            errorMessageBox("Post field is empty", TITLE_ERROR);
        }
        else if(usernameField.getText().isEmpty()){
            isValid = false;
            errorMessageBox("Username field is empty", TITLE_ERROR);
        }
        else if(new String(passwordField.getPassword()).isEmpty()){
            isValid = false;
            errorMessageBox("Password field is empty", TITLE_ERROR);
        }
        else if(passwordField.getPassword().length >= PASSWORD_LENGTH) {
            isValid = false;
            errorMessageBox("Password is too long", TITLE_ERROR);
        }
        else if(new String(confirmPasswordField.getPassword()).isEmpty()){
            isValid = false;
            errorMessageBox("The confirm password field is empty", TITLE_ERROR);
        }
        else if((new String(confirmPasswordField.getPassword()).compareTo(new String(passwordField.getPassword()))) != 0){
            isValid = false;
            errorMessageBox("Confirm password does not match", TITLE_ERROR);
        }
        
        return isValid;
    }
    /**
     * Get the name from the form and store it in a array
     * @return
     * Array with 2 positions. String{firstname,lastname}
     */
    public String[] getName(){
        String[] name = new String[2];
        name[model.FIRSTNAME_POS] = firstNameField.getText();
        name[model.LASTNAME_POS] = lastNameField.getText();
        return name;
    }
    /**
     * Get the DOB from the form and return it as an array
     * @return
     * Array{day,month,year}
     */
    public int[] getDOB(){    
        int[] dob = {0,0,0};
        if(dayField.getText()!=null){
            dob[model.DOB_DAY_POS] = Integer.parseInt(dayField.getText());
        }       
        if(monthField.getText()!=null){
            dob[model.DOB_MONTH_POS] = Integer.parseInt(monthField.getText());
        }
        if(yearField.getText()!=null){
            dob[model.DOB_YEAR_POS] = Integer.parseInt(yearField.getText());
        }
               
        return dob;
    }
    /**
     * Get the address from the form and return it as an array
     * @return
     * Arrat{addres,suburb,state,postcode}
     */
    public String[] getAddress(){
        String[] address = new String[4];
        address[model.ADDRESS_POS] = addressAddField.getText();
        address[model.SUBURB_POS] = addressSuburbField.getText();
        address[model.STATE_POS] = addressStateField.getText();
        address[model.POSTCODE_POS] = addressPostField.getText();
        
        return address;
    }
    /**
     * Get the username and password from the form abd return it as an array
     * @return
     * Array{username,password,confirmpass}
     */
    public String[] getUserPass(){
        String [] userPass = new String[3];
        
        userPass[model.USERNAME_POS] = usernameField.getText();
        userPass[model.PASSWORD_POS] = new String(passwordField.getPassword());
        userPass[model.CONFIRM_POS] = new String(confirmPasswordField.getPassword());
              
        return userPass;
    }

    /*  author Tristan
     * This function is called when an error is detected
     * The caller passes in a message and title to printed with in a message box
     */ 
    public void errorMessageBox(String m, String t){
        if(m.length() == 0 ){
            System.out.println("String error message in " + this.toString() + "is to small");
        }
        else{
            JOptionPane.showMessageDialog(frame, m, t, JOptionPane.ERROR_MESSAGE);
        }
    }
}
